package com.ruoyi.project.charging.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.project.charging.domain.*;
import com.ruoyi.project.charging.mapper.*;
import com.ruoyi.project.common.exception.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.charging.service.ITChargingMqttMsgService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 岸电MQTT消息原始数据Service业务层处理
 * 
 * @author Yaoxuan Mo
 * @date 2025-07-28
 */
@Service
public class TChargingMqttMsgServiceImpl implements ITChargingMqttMsgService 
{
    @Autowired
    private TChargingMqttMsgMapper tChargingMqttMsgMapper;
    
    @Autowired
    private TChargingMqttMsgConvertMapper tChargingMqttMsgConvertMapper;
    
    @Autowired
    private CChargingProjectMapper cChargingProjectMapper;
    
    @Autowired
    private CChargingCollectorMapper cChargingCollectorMapper;
    
    @Autowired
    private CChargingDeviceMapper cChargingDeviceMapper;
    
    @Autowired
    private CChargingPointMapper cChargingPointMapper;
    
    @Autowired
    private CChargingBitMapper cChargingBitMapper;

    /**
     * 查询岸电MQTT消息原始数据
     * 
     * @param msgid 岸电MQTT消息原始数据主键
     * @return 岸电MQTT消息原始数据
     */
    @Override
    public TChargingMqttMsg selectTChargingMqttMsgByMsgid(String msgid)
    {
        return tChargingMqttMsgMapper.selectTChargingMqttMsgByMsgid(msgid);
    }

    /**
     * 查询岸电MQTT消息原始数据列表
     * 
     * @param tChargingMqttMsg 岸电MQTT消息原始数据
     * @return 岸电MQTT消息原始数据
     */
    @Override
    public List<TChargingMqttMsg> selectTChargingMqttMsgList(TChargingMqttMsg tChargingMqttMsg)
    {
        return tChargingMqttMsgMapper.selectTChargingMqttMsgList(tChargingMqttMsg);
    }

    /**
     * 新增岸电MQTT消息原始数据
     * 
     * @param tChargingMqttMsg 岸电MQTT消息原始数据
     * @return 结果
     */
    @Override
    public int insertTChargingMqttMsg(TChargingMqttMsg tChargingMqttMsg)
    {
        return tChargingMqttMsgMapper.insertTChargingMqttMsg(tChargingMqttMsg);
    }

    /**
     * 修改岸电MQTT消息原始数据
     * 
     * @param tChargingMqttMsg 岸电MQTT消息原始数据
     * @return 结果
     */
    @Override
    public int updateTChargingMqttMsg(TChargingMqttMsg tChargingMqttMsg)
    {
        return tChargingMqttMsgMapper.updateTChargingMqttMsg(tChargingMqttMsg);
    }

    /**
     * 批量删除岸电MQTT消息原始数据
     * 
     * @param msgids 需要删除的岸电MQTT消息原始数据主键
     * @return 结果
     */
    @Override
    public int deleteTChargingMqttMsgByMsgids(String[] msgids)
    {
        return tChargingMqttMsgMapper.deleteTChargingMqttMsgByMsgids(msgids);
    }

    /**
     * 删除岸电MQTT消息原始数据信息
     * 
     * @param msgid 岸电MQTT消息原始数据主键
     * @return 结果
     */
    @Override
    public int deleteTChargingMqttMsgByMsgid(String msgid)
    {
        return tChargingMqttMsgMapper.deleteTChargingMqttMsgByMsgid(msgid);
    }

    @Override
    public List<TChargingMqttMsg> selectAllTChargingMqttMsgNotConvert() {
        return tChargingMqttMsgMapper.selectAllTChargingMqttMsgNotConvert();
    }

    @Override
    @Transactional
    public void convertOriginalTChargingMqttMsg(TChargingMqttMsg tChargingMqttMsg) {
        List<CChargingProject> cChargingProjects = cChargingProjectMapper.selectAllCChargingProjectList();
        List<CChargingCollector> cChargingCollectors = cChargingCollectorMapper.selectAllCChargingCollectorList();
        List<CChargingDevice> cChargingDevices = cChargingDeviceMapper.selectAllCChargingDeviceList();
        List<CChargingPoint> cChargingPoints = cChargingPointMapper.selectAllCChargingPointList();
        List<CChargingBit> cChargingBits = cChargingBitMapper.selectAllCChargingBitList();
        
        if (tChargingMqttMsg == null){
            return;
        }

        // 校验原始MQTT消息的插入时间字段是否为空
        if (tChargingMqttMsg.getInsTim() == null) {
            throw new CustomException("插入时间字段不能为空");
        }
        // 校验原始MQTT消息的ID字段是否为空
        if (tChargingMqttMsg.getMsgid() == null) {
            throw new CustomException("原始MQTT消息的MSGID字段不能为空");
        }
        // 校验topic是否形如charging/{project_cod}/{oper_type}/{collector_cod}
        if (!tChargingMqttMsg.getTopic().matches("^charging/[\\w./-]+/[\\w./-]+/[\\w./-]+$")) {
            throw new CustomException(String.format("topic格式不正确，正确的格式为[%s]，请检查", "charging/{project_cod}/{oper_type}/{collector_cod}"));
        }

        List<String> topics = Arrays.asList(tChargingMqttMsg.getTopic().split("/"));
        String projectCod = topics.get(1);
        String collectorCod = topics.get(3);
        
        // 校验project_cod
        if (!cChargingProjects.stream().map(CChargingProject::getProjectCod).collect(Collectors.toList()).contains(projectCod)){
            throw new CustomException(String.format("项目编码[%s]不存在", projectCod));
        }
        // 校验collector_cod
        if (!cChargingCollectors.stream().map(CChargingCollector::getCollectorCod).collect(Collectors.toList()).contains(collectorCod)){
            throw new CustomException(String.format("采集器编码[%s]不存在", collectorCod));
        }
        
        String payload = tChargingMqttMsg.getPayload();
        if (!payload.contains("{") || !payload.contains("}")){
            throw new CustomException("数据库存储的payload内容有缺失");
        }

        // 将payload字符串转换为JSON对象
        JSONObject payloadJson = JSONObject.parseObject(payload);
        // 从payload中取出实际数据
        JSONObject dataJson = payloadJson.getJSONObject(collectorCod.toUpperCase());
        
        if (collectorCod.equals("plc01")){
            List<String> deviceCodErrorList = new ArrayList<>();
            for (String deviceCod : dataJson.keySet()){
                if (!cChargingDevices.stream().map(CChargingDevice::getDeviceCod).collect(Collectors.toList()).contains(deviceCod)){
                    deviceCodErrorList.add(deviceCod);
                }
            }
            if (deviceCodErrorList.size() > 0){
                throw new CustomException(String.format("plc01采集器的MQTT消息体中，下列设备编码[%s]不存在，请检查", String.join(",",deviceCodErrorList)));
            }

            TChargingMqttMsgConvert tChargingMqttMsgConvert = new TChargingMqttMsgConvert();
            tChargingMqttMsgConvert.setMonitorTim(tChargingMqttMsg.getInsTim());
            tChargingMqttMsgConvert.setProjectCod(projectCod);
            tChargingMqttMsgConvert.setCollectorCod(collectorCod);
            tChargingMqttMsgConvert.setMsgOriginId(tChargingMqttMsg.getMsgid());
            for (String deviceCod : dataJson.keySet()){
                tChargingMqttMsgConvert.setDeviceCod(deviceCod);
                int deviceValue = dataJson.getIntValue(deviceCod);
                
                List<CChargingBit> cChargingBitsOfCertainDevice = cChargingBits.stream().filter(cChargingBit -> cChargingBit.getProjectCod().equals(projectCod) &&
                        cChargingBit.getCollectorCod().equals(collectorCod) &&
                        cChargingBit.getDeviceCod().equals(deviceCod) &&
                        cChargingBit.getIsSafe().equals("1") &&
                        cChargingBit.getIsEnable().equals("1")).collect(Collectors.toList());
                for (CChargingBit cChargingBitItem : cChargingBitsOfCertainDevice){
                    tChargingMqttMsgConvert.setMsgConvertId(UUID.randomUUID().toString());
                    tChargingMqttMsgConvert.setItemCod(cChargingBitItem.getBitCod());
                    int itemValue = deviceValue >> (cChargingBitItem.getBitSeq() - 1) & 1;
                    tChargingMqttMsgConvert.setItemVal(String.valueOf(itemValue));

                    tChargingMqttMsgConvertMapper.insertTChargingMqttMsgConvert(tChargingMqttMsgConvert);
                }
            }
        }

        if (collectorCod.equals("g6a01")){
            List<String> pointCodErrorList = new ArrayList<>();
            for (String pointCod : dataJson.keySet()){
                if (!cChargingPoints.stream().map(CChargingPoint::getPointCod).collect(Collectors.toList()).contains(pointCod)){
                    pointCodErrorList.add(pointCod);
                }
            }
            if (pointCodErrorList.size() > 0){
                throw new CustomException(String.format("g6a01采集器的MQTT消息体中，下列测点编码[%s]不存在，请检查", String.join(",",pointCodErrorList)));
            }

            TChargingMqttMsgConvert tChargingMqttMsgConvert = new TChargingMqttMsgConvert();
            tChargingMqttMsgConvert.setMonitorTim(tChargingMqttMsg.getInsTim());
            tChargingMqttMsgConvert.setProjectCod(projectCod);
            tChargingMqttMsgConvert.setCollectorCod(collectorCod);
            tChargingMqttMsgConvert.setMsgOriginId(tChargingMqttMsg.getMsgid());
            for (String itemCod : dataJson.keySet()){
                tChargingMqttMsgConvert.setMsgConvertId(UUID.randomUUID().toString());
                String itemValue = dataJson.getString(itemCod);
                tChargingMqttMsgConvert.setItemCod(itemCod);
                tChargingMqttMsgConvert.setItemVal(String.valueOf(itemValue));
                
                CChargingPoint cChargingPoint = new CChargingPoint();
                cChargingPoint.setPointCod(itemCod);
                cChargingPoint = cChargingPointMapper.selectCChargingPointList(cChargingPoint).get(0);
                tChargingMqttMsgConvert.setDeviceCod(cChargingPoint.getDeviceCod());

                tChargingMqttMsgConvertMapper.insertTChargingMqttMsgConvert(tChargingMqttMsgConvert);
            }
        }
    }

    @Override
    public void handleConvertSuccess(TChargingMqttMsg tChargingMqttMsg) {
        tChargingMqttMsgMapper.handleConvertSuccess(tChargingMqttMsg);
    }

    @Override
    public void handleConvertFail(TChargingMqttMsg tChargingMqttMsg, String failReason) {
        tChargingMqttMsgMapper.handleConvertFail(tChargingMqttMsg, failReason);
    }
}
